package com.lingyuan.discounts.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lingyuan.common.core.domain.R;
import com.lingyuan.common.core.domain.vo.cart.CartItemVo;
import com.lingyuan.common.core.domain.vo.sms.*;
import com.lingyuan.common.core.exception.ServiceException;
import com.lingyuan.common.core.utils.DateUtils;
import com.lingyuan.discounts.constant.CouponAmountEnum;
import com.lingyuan.discounts.domain.Coupon;
import com.lingyuan.discounts.domain.CouponHistory;
import com.lingyuan.discounts.domain.request.CouponRequest;
import com.lingyuan.discounts.factory.DiscountStrategyFactory;
import com.lingyuan.discounts.mapper.CouponMapper;
import com.lingyuan.discounts.remote.CartRemoteService;
import com.lingyuan.discounts.service.CouponHistoryService;
import com.lingyuan.discounts.service.CouponService;
import com.lingyuan.discounts.tactics.DiscountStrategy;
import com.lingyuan.discounts.tactics.impl.FixedDiscountStrategy;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

/**
 * @Author: Li Hao Xuan
 * @name: CouponServiceImpl
 * @Description TODO
 */
@Service
public class CouponServiceImpl extends ServiceImpl<CouponMapper,Coupon> implements CouponService {

    @Autowired
    private CouponMapper couponMapper;

    @Autowired
    private CouponHistoryService couponHistoryService;
    @Autowired
    private CartRemoteService cartRemoteService;
    @Autowired
    private DiscountStrategyFactory discountStrategyFactory;
    /**
     * 查询优惠券列表
     * @param couponRequest
     * @return
     */
    @Override
    public List<Coupon> findCouponList(CouponRequest couponRequest) {
        QueryWrapper<Coupon> queryWrapper = Wrappers.query();
        if(couponRequest.getCouponName()!=null && !"".equals(couponRequest.getCouponName())){
            queryWrapper.like("coupon_name",couponRequest.getCouponName());
        }
        if(couponRequest.getStartTime()!=null){
            queryWrapper.ge("start_time",couponRequest.getStartTime());
        }
        if(couponRequest.getEndTime()!=null){
            queryWrapper.le("end_time",couponRequest.getEndTime());
        }
        List<Coupon> list = this.list(queryWrapper);
        return list;
    }

    /**
     * 新增优惠券
     * @param coupon
     */
    @Override
    public void addCoupon(Coupon coupon) {
        this.save(coupon);
    }

    /**
     * 修改优惠券
     * @param coupon
     */
    @Override
    public void updCoupon(Coupon coupon) {
        this.updateById(coupon);
    }

    /**
     * 删除优惠券
     * @param id
     */
    @Override
    public void delCoupon(Long id) {
        this.removeById(id);
    }


    /**
     * 优惠券计算商品价格
     * @return CouponSkuIdsVo
     */
    @Override
    public CouponSkuIdsVo findCouponSkuIdsVo(ComputeVo computeVo) {
        Long couponId = computeVo.getCouponId();
        //查询优惠券信息
        Coupon coupon = couponMapper.findCouponId(couponId);
        Date nowDate = new Date();
        if (nowDate.before(coupon.getStartTime())){
            String dateTime = DateUtils.getDateTime(coupon.getStartTime());
            throw new ServiceException("活动会在"+dateTime+"开启,到时候再使用吧~");
        }
        if (nowDate.after(coupon.getEndTime())){
            String dateTime = DateUtils.getDateTime(coupon.getEndTime());
            throw new ServiceException("活动在"+dateTime+"已经结束啦,持续关注商城后续优惠多多哦~");
        }
        //全场通用
        String discountBeanName =  getDiscountBeanName(coupon);
        if (discountBeanName == null || "".equals(discountBeanName)){
            throw new ServiceException(coupon.getCouponName()+"不满足使用条件");
        }
        DiscountStrategy strategy = discountStrategyFactory.getStrategy(discountBeanName);
        //优惠规则
        CouponSkuIdsVo couponSkuIdsVo = strategy.calculateDiscount(computeVo.getProductList(), coupon.getAmount());
        return couponSkuIdsVo;
    }

    private static String getDiscountBeanName(Coupon coupon) {
        if (coupon.getUseType() == 0){
            if (coupon.getAmountType() == CouponAmountEnum.PRICE_FIXED.getCode()){
                return CouponAmountEnum.PRICE_FIXED.getName();
            }
            if (coupon.getAmountType() == CouponAmountEnum.PRICE_PERCENT.getCode()){
                return CouponAmountEnum.PRICE_PERCENT.getName();
            }
            if (coupon.getAmountType() == CouponAmountEnum.PAY_NUM_PERCENT.getCode()){
                return CouponAmountEnum.PAY_NUM_PERCENT.getName();
            }
            if (coupon.getAmountType() == CouponAmountEnum.PAY_NUM_FIXED.getCode()){
                return CouponAmountEnum.PAY_NUM_FIXED.getName();
            }
        }
        return null;
    }

    @Override
    public Coupon findCouponId(Long couponId) {
        return couponMapper.findCouponId(couponId);
    }

    @Override
    public  List<CouponMemberVo> findSkuMinPrice(String skuIds) {
        //获取用户能使用的优惠券
        Long userId = 1L;
        // 查询用户可以使用的优惠券
        List<CouponHistory> couponHistoryList = couponHistoryService.list(new QueryWrapper<CouponHistory>().lambda()
                .eq(CouponHistory::getMemberId, userId).eq(CouponHistory::getUseType,0));
        // 优惠券id集合
        List<Long> couponIds = couponHistoryList.stream().map(CouponHistory::getCouponId).collect(Collectors.toList());
//        String couponIds = list.stream().map(String::valueOf).collect(Collectors.joining(","));
       if (CollectionUtils.isEmpty(couponIds)){
           return null;
       }
        // 查询优惠券信息
        List<Coupon> couponList = this.list(new LambdaQueryWrapper<Coupon>().in(Coupon::getId,couponIds));
        // 封装优惠券信息
        List<CouponMemberVo> couponMemberVoList = couponList.stream().map(coupon -> {
            CouponMemberVo couponMemberVo = new CouponMemberVo();
            //拷贝
            BeanUtils.copyProperties(coupon,couponMemberVo);
            return couponMemberVo;
        }).collect(Collectors.toList());
        // 获取购物车信息
        R<List<CartItemVo>> bySkuIdsCartEntityList = cartRemoteService.findBySkuIdsCartEntityList(skuIds);
        if (bySkuIdsCartEntityList.getCode() != 200){
            throw new ServiceException("获取购物车信息失败");
        }
        // 获取商品总价
        List<CartItemVo> cartItemVoList = bySkuIdsCartEntityList.getData();
        // 遍历优惠券
        List<CouponMemberVo> couponMemberVos = couponMemberVoList.stream().map(couponMemberVo -> {
                    //查询优惠券信息
                    Date nowDate = new Date();
                    if (nowDate.before(couponMemberVo.getStartTime())){
                        return null;
                    }
                    if (nowDate.after(couponMemberVo.getEndTime())){
                        return null;
                    }
                    //全场通用
                    String discountBeanName = getDiscountBeanName(couponMemberVo.getUseType(), couponMemberVo.getAmountType());
                    DiscountStrategy strategy = discountStrategyFactory.getStrategy(discountBeanName);
                    //优惠规则
                    CouponSkuIdsVo couponSkuIdsVo = strategy.calculateDiscount(cartItemVoList, couponMemberVo.getAmount());
                    if (couponSkuIdsVo == null) {
                        return null;
                    }
                    couponMemberVo.setPrice(couponSkuIdsVo.getTotalPrice());
                    return couponMemberVo;
                }).filter(Objects::nonNull)
                .sorted(Comparator.comparing(CouponMemberVo::getPrice))
                .collect(Collectors.toList());
        // 设置优惠券状态
        Optional<CouponMemberVo> firstCouponMemberVo = couponMemberVos.stream().findFirst();
        firstCouponMemberVo.ifPresent(couponMemberVo -> {
            couponMemberVo.setStatus(1);
        });
        return couponMemberVos;

    }

    private static String getDiscountBeanName(Integer couponMemberVo, Integer couponMemberVo1) {
        String discountBeanName = "";
        if (couponMemberVo == 0) {
            if (couponMemberVo1 == CouponAmountEnum.PRICE_FIXED.getCode()) {
                discountBeanName = CouponAmountEnum.PRICE_FIXED.getName();
            }
            if (couponMemberVo1 == CouponAmountEnum.PRICE_PERCENT.getCode()) {
                discountBeanName = CouponAmountEnum.PRICE_PERCENT.getName();
            }
            if (couponMemberVo1 == CouponAmountEnum.PAY_NUM_PERCENT.getCode()) {
                discountBeanName = CouponAmountEnum.PAY_NUM_PERCENT.getName();
            }
            if (couponMemberVo1 == CouponAmountEnum.PAY_NUM_FIXED.getCode()) {
                discountBeanName = CouponAmountEnum.PAY_NUM_FIXED.getName();
            }
        }
        return discountBeanName;
    }

    // 修改优惠券使用数量
    @Override
    public void updUseCount(Long id) {
        couponMapper.updUseCount(id);
    }


}
